#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <sqlite3.h>
#import <UIKit/UIApplication.h>
#import <SpringBoard/SBApplicationController.h>
#import <SpringBoard/SBApplication.h>
#import "../LockInfo/Plugin.h"

#import "PIIntegration.h"
#import "PIPlugin.h"
#import "PITodoPreview.h"

#define SECTION_BORDER 10
#define SECTION_WIDTH 280


@implementation PITodoPreview

@synthesize plugin, todoListP, view, dbPath, navControl, sections;


-(void)dealloc {
    [plugin release];
    [todoListP release];
	[view release];
	[dbPath release];
	[navControl release];
	[sections release];
	
    [super dealloc];
}

- (id) initWithFrame: (CGRect*) r withList: (NSArray*) l atIndex: (NSIndexPath*) i withPlugin: (PIPlugin*) p {
	self = [super initWithFrame: *r];
	
	if (self)
    {
		self.todoListP = l;
		[self setIndex: i.row];
		[self setRect: r];
        self.plugin = p;
		[self buildPreview];
		
		[self setForIndex:i.row];
	}
    
    return self;
}

- (void) setRect: (CGRect*) r {
	rect = r;
}

- (CGRect*) getRect {
    return rect;
}

- (void) setIndex: (int) i {
	indexRow = i;
}

- (int) getIndex {
	return indexRow;
}

- (void) buildPreview {
	NSBundle* bundle = [NSBundle bundleForClass:[self class]];

	UIBarButtonItem* closeBtn = [[[UIBarButtonItem alloc]
								  initWithTitle:localize(bundle, @"Detail/Button/Done")
										  style:UIBarButtonItemStyleBordered 
										 target:self.plugin.plugin
								         action:@selector(dismissPreview)] autorelease];

	UIImage* btnUp = [UIImage imageWithContentsOfFile:@"/Applications/MobileMail.app/arrowup.png"];								  
	UIImage* btnDown = [UIImage imageWithContentsOfFile:@"/Applications/MobileMail.app/arrowdown.png"];								  
	self.navControl = [[[UISegmentedControl alloc]
						initWithItems:
						[NSArray arrayWithObjects:
						 btnUp,
						 btnDown,
						 nil]] autorelease];
	
	if ((btnUp == nil) || (btnDown == nil))
		self.navControl = [[[UISegmentedControl alloc]
							initWithItems:
							[NSArray arrayWithObjects:
							 localize(bundle, @"Detail/Button/Up"),
							 localize(bundle, @"Detail/Button/Down"),
							 nil]] autorelease];
	
	self.navControl.segmentedControlStyle = UISegmentedControlStyleBar;
	self.navControl.momentary = YES;

	[self.navControl addTarget:self
						action:@selector(navigate:)
			  forControlEvents:UIControlEventValueChanged];
	
	UIBarButtonItem* navBtn = [[[UIBarButtonItem alloc] initWithCustomView:self.navControl] autorelease];
	navBtn.width = 100.0;

	UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc]
									  initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
														   target:nil
									                       action:nil];

	const CGFloat toolbarHeight = 44;
	CGRect navBarFrame = CGRectMake(0, 0, rect->size.width, toolbarHeight);
	CGRect taskBarFrame = CGRectMake(0, rect->size.height - toolbarHeight, rect->size.width, toolbarHeight);
	CGRect scrollFrame = CGRectMake(0, navBarFrame.size.height, rect->size.width, rect->size.height - taskBarFrame.size.height - navBarFrame.size.height);

	UIToolbar* nav = [[[UIToolbar alloc] initWithFrame:navBarFrame] autorelease];
	nav.barStyle = UIBarStyleBlackOpaque;
	nav.items = [NSArray arrayWithObjects:
				 closeBtn,
				 flexibleSpace,
				 navBtn,
				 nil];
	[self addSubview:nav];

#ifdef DEBUG
	UIToolbar* task = [[[UIToolbar alloc] initWithFrame:taskBarFrame] autorelease];
	task.barStyle = UIBarStyleBlackOpaque;
	task.items = [NSArray arrayWithObjects:
					 flexibleSpace,
					 nil];
	[self addSubview:task];
#else
	scrollFrame.size.height += taskBarFrame.size.height;
#endif
	
    UITableView* tableView = [[UITableView alloc] initWithFrame:scrollFrame style:UITableViewStyleGrouped];
	tableView.dataSource = self;
	tableView.delegate = self;
	tableView.allowsSelection = NO;
	
	[self addSubview:tableView];
	self.view = tableView;

	[tableView release];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	return [self.sections count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	NSArray* sect = [self.sections objectAtIndex:section];
	return [sect count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
	return nil;
}

- (void) setForIndex:(int)i {
	[self setIndex:i];
	NSBundle* bundle = [NSBundle bundleForClass:[self class]];
	
	[self.navControl setEnabled:(i > 0) forSegmentAtIndex:0];
	[self.navControl setEnabled:(i < ((int)[self.todoListP count] - 1)) forSegmentAtIndex:1];
	
	NSDictionary* elem = [self.todoListP objectAtIndex: [self getIndex]];
	NSNumber* key = [elem objectForKey:@"key"];
	
	NSString *sql = @"select t.title, t.startdate, t.duedate, t.duedatetime, t.priority, t.fcpriority, t.flagged, t.action, t.icon, t.notes, t.percentcomplete, a.title, c.name, p.title, t.calendarid, k.title, t.id, group_concat(g.title, ', ') from task t left join task a on t.parenttaskid = a.id left join context c on t.contextid = c.id left join calendar k on t.calendarid = k.id left join task p on t.projectid = p.id left join itemtagmap m on m.itemid = t.id left join tag g on m.tagid = g.id where t.id = %s order by g.title";
	sql = [sql stringByReplacingOccurrencesOfString:@"%s" withString:[key stringValue]];
	
	NSLog(@"LI:PITodo: Executing SQL %@", sql);

	sqlite3 *database = NULL;
	@try {		
		if (sqlite3_open([self.plugin.dbPath UTF8String], &database) != SQLITE_OK) {
			NSLog(@"LI:PITodo: Failed to open database.");
			return;
		}
		
		// Setup the SQL Statement and compile it for faster access
		sqlite3_stmt *compiledStatement = NULL;
		
		@try {
			if (sqlite3_prepare_v2(database, [sql UTF8String], -1, &compiledStatement, NULL) != SQLITE_OK) {
				NSLog(@"LI:PITodo: Failed to prepare statement: %s", sqlite3_errmsg(database));
				return;
			}
			
			DebugLog(@"LI:PITodo: Executed SQL OK");
			
			// Read the results
			if (sqlite3_step(compiledStatement) == SQLITE_ROW) {
				const char *cTitle = (const char*)sqlite3_column_text(compiledStatement, 0);
				double cStart = sqlite3_column_double(compiledStatement, 1);
				double cDue = sqlite3_column_double(compiledStatement, 2);
				double cDueTime = sqlite3_column_double(compiledStatement, 3);
				int cImportance = sqlite3_column_int(compiledStatement, 4);
				const char *cPriority = (const char*)sqlite3_column_text(compiledStatement, 5);
				BOOL cFlagged = sqlite3_column_int(compiledStatement, 6) != 0;
				int cAction = sqlite3_column_int(compiledStatement, 7);
				const char *cIcon = (const char*)sqlite3_column_text(compiledStatement, 8);
				const char *cNote = (const char*)sqlite3_column_text(compiledStatement, 9);
				int cPercentComplete = sqlite3_column_int(compiledStatement, 10);
				const char *cParent = (const char*)sqlite3_column_text(compiledStatement, 11);
				const char *cContext = (const char*)sqlite3_column_text(compiledStatement, 12);
				const char *cProject = (const char*)sqlite3_column_text(compiledStatement, 13);
				int cCalendarID = sqlite3_column_int(compiledStatement, 14);
				const char *cCalendar = (const char*)sqlite3_column_text(compiledStatement, 15);
				int cTaskID = sqlite3_column_int(compiledStatement, 16);
				const char *cTags = (const char*)sqlite3_column_text(compiledStatement, 17);
				
				NSString* icon = [NSString stringWithUTF8String:(cIcon == NULL ? "" : cIcon)];
				NSString* title = [NSString stringWithUTF8String:(cTitle == NULL ? "" : cTitle)];
				
				if ([icon length] > 0)
					title = [NSString stringWithFormat:@"%@ %@", title, icon];

				NSMutableDictionary* titleRows = [NSMutableDictionary dictionaryWithCapacity:3];
				[titleRows setObject:title
							  forKey:@"title"];
				if (cFlagged) {
					NSString* iconFile = [NSString stringWithFormat:@"%@/star_yellow.png", [plugin appPath]];
					UIImage* icon = [UIImage imageWithContentsOfFile:iconFile];
					if (icon != nil)
						[titleRows setObject:icon forKey:@"icon"];
				}
				[titleRows setObject:[NSNumber numberWithFloat:([UIFont labelFontSize] + 3.0)]
							  forKey:@"size"];

				NSArray* titleSect = [NSArray arrayWithObjects:
									  titleRows,
									  nil];
				
				// Dates section
				NSMutableArray* datesSect = [NSMutableArray arrayWithCapacity:2];
				if (cStart != 0) {
					[datesSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  localize(bundle, @"Detail/Start"), @"title",
					  [PIIntegration formatDate:bundle
										   date:[NSNumber numberWithDouble:cStart]
										   time:false
										 format:DateFormatterLongFormat], @"value",
					  nil]];
#ifdef DEBUG
					[datesSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  @"Start Date*", @"title",
					  [NSString stringWithFormat:@"%@", [[[NSDate alloc] initWithTimeIntervalSinceReferenceDate:cStart] autorelease]], @"value",
					  nil]];
					[datesSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  @"Start Date*", @"title",
					  [NSString stringWithFormat:@"%F", cStart], @"value",
					  nil]];
#endif
				 }
				 if (cDueTime != 0) {
					[datesSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  localize(bundle, @"Detail/Due"), @"title",
					  [PIIntegration formatDate:bundle
										   date:[NSNumber numberWithDouble:cDueTime]
										   time:true
										 format:DateFormatterLongFormat], @"value",
					  nil]];
#ifdef DEBUG
					[datesSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  @"Due Time*", @"title",
					  [NSString stringWithFormat:@"%@", [[[NSDate alloc] initWithTimeIntervalSinceReferenceDate:cDueTime] autorelease]], @"value",
					   nil]];
					 [datesSect addObject:
					  [NSDictionary dictionaryWithObjectsAndKeys:
					   @"Due Time*", @"title",
					   [NSString stringWithFormat:@"%F", cDueTime], @"value",
					   nil]];
#endif
					 }
				else if (cDue != 0) {
					[datesSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  localize(bundle, @"Detail/Due"), @"title",
					  [PIIntegration formatDate:bundle
										   date:[NSNumber numberWithDouble:cDue]
										   time:false
										 format:DateFormatterLongFormat], @"value",
					  nil]];
#ifdef DEBUG
					[datesSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  @"Due Date*", @"title",
					  [NSString stringWithFormat:@"%@", [[[NSDate alloc] initWithTimeIntervalSinceReferenceDate:cDue] autorelease]], @"value",
					   nil]];
					[datesSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  @"Due Date*", @"title",
					  [NSString stringWithFormat:@"%F", cDue], @"value",
					  nil]];
#endif
				}					
				//				double duetime = cDueTime != 0 ? cDueTime : cDue;
//				if (duetime != 0) {
//					NSDate* dueDate = [[[NSDate alloc] initWithTimeIntervalSinceReferenceDate:duetime] autorelease];
//					NSDate *today = [NSDate date];
//					if ([dueDate compare:today] == NSOrderedAscending) 
//						[datesSect addObject:
//						 [NSDictionary dictionaryWithObjectsAndKeys:
//						  localize(bundle, @"Overdue"), @"title",
//						  self.plugin.overdueColor, @"color",
//						  nil]];
//				}
				
				
				// Context section
				NSMutableArray* contextSect = [NSMutableArray arrayWithCapacity:3];
#ifdef DEBUG
				[contextSect addObject:
				 [NSDictionary dictionaryWithObjectsAndKeys:
				  @"ID", @"title",
				  [NSString stringWithFormat:@"%i", cTaskID], @"value",
				  nil]];
#endif

				NSString* context = [NSString stringWithUTF8String:(cContext == NULL ? "" : cContext)];
				if ([context length] > 0)
					[contextSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  localize(bundle, @"Detail/Context"), @"title",
					  context, @"value",
					  nil]];
				
				NSString* project = [NSString stringWithUTF8String:(cProject == NULL ? "" : cProject)];
				if ([project length] > 0)
					[contextSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  localize(bundle, @"Detail/Project"), @"title",
					  project, @"value",
					  nil]];
				
				NSString* tags = [NSString stringWithUTF8String:(cTags == NULL ? "" : cTags)];
				if ([tags length] > 0)
					[contextSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  localize(bundle, @"Detail/Tags"), @"title",
					  tags, @"value",
					  nil]];
				
				NSString* parent = [NSString stringWithUTF8String:(cParent == NULL ? "" : cParent)];
				if ([parent length] > 0)
					[contextSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  localize(bundle, @"Detail/Parent"), @"title",
					  parent, @"value",
					  nil]];
				
				NSString* calendar = [NSString stringWithUTF8String:(cCalendar == NULL ? "" : cCalendar)];
				if (cCalendarID == -2)
					calendar = localize(bundle, @"Detail/Internal Task Calendar");
				if ([calendar length] > 0)
					[contextSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  localize(bundle, @"Detail/Calendar"), @"title",
					  calendar, @"value",
					  nil]];
				
				
				// Progress section

				NSMutableArray* progressSect = [NSMutableArray arrayWithCapacity:4];
				[progressSect addObject:
				 [NSDictionary dictionaryWithObjectsAndKeys:
				  localize(bundle, @"Detail/Action"), @"title",
				  localize(bundle, [PIIntegration nameForAction:cAction]), @"value",
				  nil]];

				NSString* importance = localize(bundle, [PIIntegration nameForImportance:cImportance]);
				NSString* priority = [NSString stringWithUTF8String:(cPriority == NULL ? "" : cPriority)];
				if ([priority length] > 0) {
					priority = [NSString stringWithFormat:@"%@\n%@", priority, importance];
					NSString* title = [NSString stringWithFormat:@"%@\n%@", localize(bundle, @"Detail/Priority"), localize(bundle, @"Detail/Importance")];
					
					[progressSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  title, @"title",
					  priority, @"value",
					  [NSNumber numberWithInt:2], @"lines",
					  nil]];
				}
				else {
					[progressSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  localize(bundle, @"Detail/Importance"), @"title",
					  importance, @"value",
					  nil]];
				}
				
				[progressSect addObject:
				 [NSDictionary dictionaryWithObjectsAndKeys:
				  localize(bundle, @"Detail/Complete"), @"title",
				  [NSString stringWithFormat:@"%i%%", cPercentComplete], @"value",
				  nil]];
				
				
				// Notes section
				NSMutableArray* notesSect = [NSMutableArray arrayWithCapacity:1];
				NSString* note = [NSString stringWithUTF8String:(cNote == NULL ? "" : cNote)];
				if ([note length] > 0)
					[notesSect addObject:
					 [NSDictionary dictionaryWithObjectsAndKeys:
					  note, @"title",
					  [NSNumber numberWithBool:YES], @"nobold",
					  [NSNumber numberWithFloat:[UIFont systemFontSize]], @"size",
					  nil]];
				
				// Build sections list
				NSMutableArray* sects = [NSMutableArray arrayWithCapacity:6];
				[sects addObject:titleSect];
				if ([datesSect count] > 0)
					[sects addObject:datesSect];
				if ([contextSect count] > 0)
					[sects addObject:contextSect];
				if ([progressSect count] > 0)
					[sects addObject:progressSect];
				if ([notesSect count] > 0)
					[sects addObject:notesSect];
				
				DebugLog(@"LI:PITodo: Detail read = %@", sects);
				
				self.sections = sects;
			}
		}
		@catch (NSException *exception) {
			NSLog(@"LI:PITodo: DB Read exception: %@", exception);
		}
		@finally {			
			if (compiledStatement != NULL)
				sqlite3_finalize(compiledStatement);
		}
	}
	@finally {
		if (database != NULL)
			sqlite3_close(database);
	}

	[self.view reloadData];
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
	int section = [indexPath indexAtPosition:0];
	NSArray* sect = [self.sections objectAtIndex:section];

	int row = [indexPath indexAtPosition:1];
	NSDictionary* elem = [sect objectAtIndex:row];
	
	NSString* title = [elem objectForKey:@"title"];
	NSString* value = [elem objectForKey:@"value"];
	NSNumber* nobold = [elem objectForKey:@"nobold"];
	NSNumber* size = [elem objectForKey:@"size"];
	if (size == nil)
		size = [NSNumber numberWithFloat:[UIFont labelFontSize]];

	if ((value == nil) || ([value length] == 0)) {
		UIImage* newIcon = [elem objectForKey:@"icon"];
		CGFloat iconWidth = (newIcon != nil) ? (newIcon.size.width + 8): 0;

		CGSize constraint = CGSizeMake(SECTION_WIDTH - iconWidth, MAXFLOAT);

		UIFont* font = nil;
		if (nobold == nil)
			font = [UIFont boldSystemFontOfSize:size.floatValue];
		else
			font = [UIFont systemFontOfSize:size.floatValue];
		CGSize titleSize = [title sizeWithFont:font constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
		
		return titleSize.height + SECTION_BORDER * 2;
	}
	else {
		CGSize titleSize = [title sizeWithFont:[UIFont boldSystemFontOfSize:17]];
		CGSize constraint = CGSizeMake(SECTION_WIDTH - titleSize.width, MAXFLOAT);
		CGSize detailSize = [value sizeWithFont:[UIFont systemFontOfSize:size.floatValue] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

		if (titleSize.height > detailSize.height)
			return titleSize.height + SECTION_BORDER * 2;
		else
			return detailSize.height + SECTION_BORDER * 2;
	}
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	int section = [indexPath indexAtPosition:0];
	NSArray* sect = [self.sections objectAtIndex:section];
	
	int row = [indexPath indexAtPosition:1];
	NSDictionary* elem = [sect objectAtIndex:row];
	
	NSString* title = [elem objectForKey:@"title"];
	NSString* value = [elem objectForKey:@"value"];
	UIImage* icon = [elem objectForKey:@"icon"];
	NSNumber* nobold = [elem objectForKey:@"nobold"];
	NSNumber* lines = [elem objectForKey:@"lines"];
	NSNumber* size = [elem objectForKey:@"size"];
	if (size == nil)
		size = [NSNumber numberWithFloat:[UIFont labelFontSize]];
	
    static NSString *MyIdentifier = @"PITodoPreview";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:MyIdentifier] autorelease];
    }

	if (nobold == nil)
		cell.textLabel.font = [UIFont boldSystemFontOfSize:size.floatValue];
	else
		cell.textLabel.font = [UIFont systemFontOfSize:size.floatValue];

    cell.textLabel.text = title;
	cell.detailTextLabel.font = [UIFont systemFontOfSize:size.floatValue];
	cell.detailTextLabel.text = value;
	cell.imageView.image = icon;
	
	if ((value != nil) && ([value length] > 0)) {
		if (lines == nil) {
			cell.textLabel.numberOfLines = 1;
			cell.detailTextLabel.numberOfLines = 0;
		}
		else {
			cell.textLabel.numberOfLines = lines.intValue;
			cell.detailTextLabel.numberOfLines = lines.intValue;
		}			
		cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
		cell.textLabel.textColor = [UIColor darkTextColor];
	}
	else {
		if (lines == nil) {
			cell.textLabel.numberOfLines = 0;
			cell.detailTextLabel.numberOfLines = 1;
		}
		else {
			cell.textLabel.numberOfLines = lines.intValue;
			cell.detailTextLabel.numberOfLines = lines.intValue;
		}			
		cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
		//cell.textLabel.textAlignment = UITextAlignmentCenter;
		
		if (nobold != nil)
			cell.textLabel.textColor = cell.detailTextLabel.textColor;
		else {
			UIColor* color = [elem objectForKey:@"color"];
			if (color == nil)
				color = [UIColor darkTextColor];
			cell.textLabel.textColor = color;
		}
	}

	return cell;
}

-(CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section {
	if (section == 0)
		return 4.0;
	else
		return 1.0;
}

-(CGFloat)tableView:(UITableView*)tableView heightForFooterInSection:(NSInteger)section {
	return 2.0;
}

-(UIView*)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section {
	return [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)] autorelease];
}

-(UIView*)tableView:(UITableView*)tableView viewForFooterInSection:(NSInteger)section {
	return [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)] autorelease];
}

-(void)navigate:(id)sender {
	UISegmentedControl *control = (UISegmentedControl *)sender;
	if ([control selectedSegmentIndex] == 0)
		[self setForIndex:[self getIndex] - 1];
	else
		[self setForIndex:[self getIndex] + 1];
}

@end
